#include "mutex.hpp"

#include "atomic.hpp"

int Monitor::TryFast(){
    intptr_t  v = intptr_t( Atomic::cmpxchg_ptr((void*)1,(void*)&_LockWord,(void*)0) );
    if( v == 0){
        return 1;
    }

    // _LockWord里存储了ParkEvent，但是最低位byte存储的是0
    for(;;){
        if((v & 1 !=0))
            return 0;
        intptr_t  u = intptr_t( Atomic::cmpxchg_ptr( (void*)(v | 1),(void*)&_LockWord,(void*)v) );
        if(v == u ){
            return 1;
        }
        v = u;
    }
}

int Monitor::TrySpin(){

    int Probes = 0;
    int SpinMax = 20;
    for(;;){
        intptr_t v = _LockWord.FullWord;
        if( (v & 1) == 0){
            intptr_t  u = intptr_t( Atomic::cmpxchg_ptr( (void*)(v | 1),(void*)&_LockWord,(void*)v) );
            if(u == v){
                return 1;
            }
            continue;
        }

        ++Probes;
        if(Probes > SpinMax){
            return 0;
        }
    }
}



void Monitor::ILock(Thread *Self){
    if(TryFast()){
        return;
    }

    if(TrySpin()){
        return;
    }
}

void Monitor::IUnlock(){

}